using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Windows.Forms;

namespace UmassGrader
{
    /// <summary>
    /// helper class to quickly locate paths or files of interest
    /// </summary>
    public class PathFinder
    {
        /// <summary>
        /// constant meaning on the local machine [or project Dir]
        /// </summary>
        public const int Local = 0;
        /// <summary>
        /// constant meaning on the remote machine [or in the working dir]
        /// </summary>
        public const int Remote = 1;

        /// <summary>
        /// directory on local machine
        /// </summary>
        private String lD;
        /// <summary>
        /// directory on remote machine
        /// </summary>
        private String rD;

        /// <summary>
        /// safety function give blank values for the local and remote diretories
        /// </summary>
        public PathFinder()
            :this(@"c:\",@"c:\")
        {}
        /// <summary>
        /// sets the values for the local and remote directories that will be accessed during the
        /// use of the programm
        /// </summary>
        /// <param name="local">the fully qualified path where local copies of source-code and
        /// othe files will be stored</param>
        /// <param name="remote">the remote directory that contains a directory for all students</param>
        public PathFinder(String local, String remote)
        {
            localDir = local;
            RemoteDir = remote; 
        }

        /// <summary>
        /// the local directory that is the parent DIR of all project DIRs
        /// </summary>
        public String localDir
        {
            get { return lD; }
            set
            {
                if (Directory.Exists(value)) lD = value;
                else
                {
                    lD = @"c:\";
                    //throw new Exception("ERROR: the local directory was changed to a directory that does not exist.\n directory has reverted back to previous value");
                    MessageBox.Show("ERROR: the local directory was changed to a directory that does not exist.\n directory has reverted back to previous value");
                }
            }
        }

        /// <summary>
        /// the remote directory that is the partent DIR of all student DIRs
        /// </summary>
        public String RemoteDir
        {
            get { return rD; }
            set
            {
                if (Directory.Exists(value)) rD = value;
                else
                {
                    rD = @"c:\";
                    MessageBox.Show("ERROR: the remote directory was changed to a directory that does not exist.\n directory has reverted back to previous value");
                    //throw new Exception("ERROR: the remote directory was changed to a directory that does not exist.\n directory has reverted back to previous value");
                }
            }
        }


        /// <summary>
        /// the Directory where cpp,obj,exe,prn,and grd files are stored for a specific project
        /// </summary>
        public String localProjectDir( Assignment prog)
        {
            return String.Format(@"{0}\{1}", lD, prog.dispName);
        }
        /// <summary>
        /// the directory where a student submits files
        /// </summary>
        public String remoteStudentDir( Student stu)
        {
            return String.Format(@"{0}\{1}", rD, stu.userName);
        }
        /// <summary>
        /// the full path of the exe file for a specific user and assignment(local only)
        /// </summary>
        public String executablePath(Student stu,  Assignment prog)
        {
            return String.Format(@"{0}\{1}.exe", localProjectDir(prog), stu.userName);
        }
        /// <summary>
        /// location of the .obj file generated during compilation
        /// </summary>
        /// <param name="stu">the student you are looking at</param>
        /// <param name="prog">the project you are grading</param>
        public String objectPath(Student stu, Assignment prog)
        {
            return String.Format(@"{0}\{1}.obj", localProjectDir(prog), stu.userName);
        }
        /// <summary>
        /// path of a .prn file
        /// </summary>
        /// <param name="stu">the student you are looking at</param>
        /// <param name="prog">the project you are grading</param>
        public String printPath( Student stu, Assignment prog)
        {
            return String.Format(@"{0}\{1}.prn", localProjectDir(prog), stu.userName);
        }
        /// <summary>
        /// full path of -grd.txt files (local or remote)
        /// </summary>
        /// <param name="stu">the student you are looking at</param>
        /// <param name="prog">Assignment being corrected</param>
        /// <param name="location">0=local, 1=remote</param>
        public String gradePath(Student stu, Assignment prog, int location)
        {
            if (location == 0)
                return String.Format(@"{0}\\{1}-grd.txt", localProjectDir(prog), stu.userName);
            else
                return String.Format(@"{0}\\{1}-grd.txt", remoteStudentDir(stu), prog.dispName);
        }
        /// <summary>
        /// the directory of photos for a class section
        /// </summary>
        public String localPhotoDir()
        {
            return String.Format(@"{0}\photos", lD);
        }
        /// <summary>
        /// the full path of a users local photo
        /// </summary>
        /// <param name="stu">the student you are looking at</param>
        /// <param name="location">0=local, 1=remote</param>
        public String photoPath( Student stu, int location)
        {
            if (location == 0)
                return String.Format(@"{0}\photo\{1}_photo.jpg", lD, stu.userName);
            else
                return String.Format(@"{0}\{1}\photo.jpg", rD, stu.userName);
        }
        /// <summary>
        /// find the files a student submits for a given project
        /// </summary>
        /// <param name="stu">the student you are looking at</param>
        /// <param name="prog">Assignment being corrected</param>
        /// <param name="num">index of the file (used for multi file project submissions)</param>
        /// <param name="location">0=local, 1=remote</param>
        public String submitablesPath(Student stu, Assignment prog, int num, int location)
        {
            if (location == 0)
                return String.Format(@"{0}\{1}_{2}", localProjectDir(prog), stu.userName, prog.submitList[num]);
            else
                return String.Format(@"{0}\{1}", remoteStudentDir(stu), prog.submitList[num]);
        }

        /// <summary>
        /// this file deals with locating a file on the local machine.
        /// a student source file can be located in the working directory 
        ///  when it is being compiled (with its original name)
        /// or it can be in the main project directory with a name like user_prog.cpp
        /// this distiguishes between them
        /// </summary>
        /// <param name="stu">the student whose source file you are looking for</param>
        /// <param name="prog">the particular assignment you are correcting</param>
        /// <param name="num">the index of the source file to be retrieved</param>
        /// <param name="location">unlike similar functions no location deals with a remote location
        /// the only options are:
        /// Local - user_prog.cpp
        /// Remote - workingdir\prog.cpp</param>
        /// <returns>the fully qualified path</returns>
        public String compilablesPath( Student stu, Assignment prog, int num, int location)
        {
            if (location == Local)

                return String.Format(@"{0}\{1}_{2}", localProjectDir(  prog), stu.userName, prog.compilableFiles()[num]);
            else
                return prog.workingDir + @"\" + prog.compilableFiles()[num];
        }
        /// <summary>
        /// find the path of a data file that will be provided as input to the student submission
        /// </summary>
        /// <param name="prog">the assignment whose data file you need to find</param>
        /// <param name="num">the index of the data file</param>
        /// <param name="location">0 = in the project folder, 1 = in the working directory</param>
        public String inputDataFilePath( Assignment prog, int num, int location)
        {
            if (location == 0)
                return String.Format(@"{0}\{1}", localProjectDir( prog), prog.inputFileList[num]);
            else
                return String.Format(@"{0}\{1}", progWorkingDirectory(prog), prog.inputFileList[num]);
        }

        /// <summary>
        /// find the path of a data file that will be redirected as input to the student submission
        /// </summary>
        /// <param name="prog">the assignment whose data file you need to find</param>
        /// <param name="num">the index of the data file</param>
        /// <param name="location">0 = in the project folder, 1 = in the working directory</param>
        public String inputRedirectPath( Assignment prog, int num, int location)
        {
            if (location == 0)
                return String.Format(@"{0}\{1}", localProjectDir(prog), prog.inputRedirectList[num]);
            else
                return String.Format(@"{0}\{1}", progWorkingDirectory(prog), prog.inputRedirectList[num]);
        }
        /// <summary>
        /// the directory where a submision will be run from (data files should be located here)
        /// </summary>
        public String progWorkingDirectory(Assignment prog)
        {
            return String.Format(@"{0}\workingDir", localProjectDir(prog));
        }
        /// <summary>
        /// find the path of a data file that should have been created by a student's running program
        /// </summary>
        public String outputDataFilePath(Assignment prog, int num)
        {
            return String.Format(@"{0}\{1}", progWorkingDirectory(prog), prog.outputFileList[num]);
        }
    }

}




